package com.whiteape.book.ui.base;

import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.header.BezierRadarHeader;
import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener;
import com.whiteape.book.R;
import com.whiteape.book.model.type.RVLayoutType;
import com.whiteape.book.utils.ToastUtils;
import com.whiteape.book.widget.itemdecoration.DividerItemDecoration;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;

/**
 * 基础的基于RecyclerView的fragment,包括
 * 智能刷新，以及批量管理功能
 */

public abstract class BaseRVFragment<T extends BaseRVFragment.Movable> extends BaseFragment {


    @BindView(R.id.refresh_layout)
    protected SmartRefreshLayout mSmartRefreshLayout;

    @BindView(R.id.recycler_view)
    protected RecyclerView mRecyclerView;

    @BindView(R.id.iv_list_or_grid)
    ImageView mIvListOrGrid;

    @BindView(R.id.iv_batch_delete)
    ImageView mIvBatch;

    @BindView(R.id.tv_collection_total)
    TextView mTvTotal;

    @BindView(R.id.tv_select_all)
    TextView mTvSelectAll;

    @BindView(R.id.tv_selected)
    TextView mTvSelected;

    @BindView(R.id.tv_delete)
    TextView mTvDelete;

    @BindView(R.id.tv_move)
    TextView mTvMove;

    @BindView(R.id.ll_menu)
    LinearLayout mMenuBottom;

    @BindView(R.id.ll_menu_top)
    LinearLayout mMenuTop;

    @BindView(R.id.tv_move_out)
    TextView mTvMoveOut;

    private BaseQuickAdapter<T, BaseViewHolder> mListAdapter;
    private BaseQuickAdapter<T, BaseViewHolder> mGridAdapter;
    private List<T> dataCanBeRemoved = new ArrayList<>();

    private boolean mGridHasBindToView = false;

    protected List<T> mSelectedList = new ArrayList<>();

    /**
     * 当前是否是选择状态
     */
    private boolean selectStateEnable = false;

    //默认是列表模式
    private boolean isListMode = true;

    /**
     * 是否允许切换List/Grid模式
     */
    private boolean isSwitchEnable = false;

    private final static int LOAD_MORE_DELAYED = 1000;

    private final static int REFRESH_DELAYED = 1500;

    /**
     * 是否需要批量删除功能
     *
     * @return
     */
    protected abstract boolean setBatchDeleteEnabled();

    /**
     * 是否可以切换list/grid
     *
     * @return
     */
    protected abstract boolean setAdapterModeSwitchEnabled();

    /**
     * 是否打开 移动分组 按钮
     */
    protected abstract boolean setMoveEnabled();

    protected boolean setMoveOutEnabled() {
        return false;
    };

    /**
     * 是否展示 一共有多少本
     * @return
     */
    protected abstract boolean showTotal();
    /**
     * 默认的排列方式是什么，这个从保存数据中拿
     *
     * @return
     */
    protected abstract boolean initListOrGrid();

    protected void onListOrGridStateChanged(boolean isList) {

    }

    ;

    /**
     * adapter列表，如果支持list/grid切换，那么必须有两个
     *
     * @return
     */
    protected abstract List<BaseQuickAdapter<T, BaseViewHolder>> setAdapter();

    /**
     * 删除的真实逻辑
     *
     * @param itemList
     */
    protected abstract void deleteItems(List<T> itemList);

    protected void moveItems(List<T> itemList){

    }

    protected void moveItemsOut(List<T> itemList){

    }


    /**
     * 点击事件
     *
     * @param adapter
     * @param view
     * @param position
     */
    protected abstract void onItemChildClickListener(BaseQuickAdapter adapter, View view, int position);


    protected abstract void onItemClickListener(BaseQuickAdapter adapter, View view, int position);

    /**
     * 批量管理状态的通知
     *
     * @param selectStateEnable
     */
    protected abstract void onSelectStateChanged(boolean selectStateEnable);


    private void dealWithData(){
        dataCanBeRemoved.clear();
        for(T t : mListAdapter.getData()){
            if(t.canMove()) {
                dataCanBeRemoved.add(t);
            }
        }

    }
    @Override
    protected void initData(Bundle savedInstanceState) {
        super.initData(savedInstanceState);
        List<BaseQuickAdapter<T, BaseViewHolder>> adapterList = setAdapter();
        mListAdapter = adapterList.get(0);
        dealWithData();
        isSwitchEnable = setAdapterModeSwitchEnabled();
        if (isSwitchEnable) {
            //表示可以切换状态，那么listAdapter和gridAdapter必须都提供
            mGridAdapter = adapterList.get(1);
        }
        isListMode = initListOrGrid();
    }


    @Override
    protected void initView(Bundle savedInstanceState) {
        super.initView(savedInstanceState);
//        if (getContext() != null) {
//            mIvBatch.setColorFilter(getContext().getResources().getColor(R.color.colorAccent));
//            mIvListOrGrid.setColorFilter(getContext().getResources().getColor(R.color.colorAccent));
//        }
        if (!setMoveEnabled()) {
            mTvMove.setVisibility(View.GONE);
        }
        if(!setMoveOutEnabled()){
            mTvMoveOut.setVisibility(View.GONE);
        }
        mTvSelectAll.setText("全选");
        mTvSelected.setVisibility(View.GONE);
        mRecyclerView.setAdapter(mListAdapter);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        if (getContext() != null) {
            mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext()));
        }

        if (isSwitchEnable) {
            mGridAdapter.bindToRecyclerView(mRecyclerView);
            mGridHasBindToView = true;
            mGridAdapter.setEmptyView(R.layout.layout_empty_default);
        }
        mListAdapter.bindToRecyclerView(mRecyclerView);
        mListAdapter.setEmptyView(R.layout.layout_empty_default);

        setupListOrGrid();

        if (!isSwitchEnable) {
            mIvListOrGrid.setVisibility(View.INVISIBLE);
        }

//        mListAdapter.setFooterView(getLayoutInflater().inflate(R.layout.layout_footer, null));
        //设置 Header 为 贝塞尔雷达 样式
        if (getContext() != null) {
            mSmartRefreshLayout.setRefreshHeader(new BezierRadarHeader(getContext()).setEnableHorizontalDrag(true));
            //设置 Footer 为 球脉冲 样式
//            mSmartRefreshLayout.setRefreshFooter(new BallPulseFooter(getContext()).setSpinnerStyle(SpinnerStyle.Scale));
            mSmartRefreshLayout.setEnableLoadMore(false);
            mSmartRefreshLayout.setPrimaryColorsId(R.color.md_grey_600, R.color.md_grey_400);
        }
    }

    public void setEmptyView(int id) {
        if (mListAdapter != null) {
            mListAdapter.setEmptyView(R.layout.layout_empty_media);
        }
        if (mGridAdapter != null) {
            mGridAdapter.setEmptyView(R.layout.layout_empty_media);

        }
    }

    @Override
    protected int getContentId() {
        return R.layout.layout_base_rv_fragment;
    }

    @Override
    protected void initEvent() {
        super.initEvent();
        eventMove();
        eventBatch();
        eventDelete();
        eventMoveOut();
        eventSelectAll();
        eventListOrGrid();
        eventRefreshView();
        eventRecyclerView();
    }

    protected int getTotalStringTemplate() {
        return R.string.book_total_template;
    }

    private void refreshMenu() {
//        if (getContext() != null) {
//            mIvBatch.setColorFilter(getContext().getResources().getColor(R.color.colorAccent));
//            mIvListOrGrid.setColorFilter(getContext().getResources().getColor(R.color.colorAccent));
//        }
        if(showTotal()) {
            mTvTotal.setText(getString(getTotalStringTemplate(), mListAdapter.getData().size()));
        }
        if(selectStateEnable){
            mTvSelected.setText("已选数量: " + mSelectedList.size());
        }
        mTvSelected.setVisibility(selectStateEnable ? View.VISIBLE : View.GONE);
        if (mListAdapter.getData().size() == 0) {
            if (isListMode) {
                mIvListOrGrid.setImageResource(R.mipmap.ico_list_unavailable);
            } else {
                mIvListOrGrid.setImageResource(R.mipmap.ico_grid_unavailable);
            }
            mIvBatch.setImageResource(R.mipmap.base_edit_normal);
            mMenuBottom.setVisibility(View.GONE);
            mTvSelectAll.setText("全选");

        } else {
            if (isListMode) {
                mIvListOrGrid.setImageResource(R.mipmap.ico_list_unavailable);
            } else {
                mIvListOrGrid.setImageResource(R.mipmap.ico_grid_unavailable);
            }
            if (selectStateEnable) {
//                mIvBatch.setImageResource(R.mipmap.ico_batch_close);
                if (getContext() != null) {
                    mIvBatch.setColorFilter(getContext().getResources().getColor(R.color.colorAccent));
                }
                mMenuBottom.setVisibility(View.VISIBLE);
                if (mSelectedList.size() > 0) {
//                    mTvDelete.setText("删除(" + mSelectedList.size() + "本)");
                    mTvDelete.setTextColor(getResources().getColor(R.color.md_grey_600));
                    mTvMove.setTextColor(getResources().getColor(R.color.md_grey_600));
//                    mTvMove.setText("移至分组(" + mSelectedList.size() + "本)");
                    mTvMoveOut.setTextColor(getResources().getColor(R.color.md_grey_600));
//                    mTvMoveOut.setText("移出分组(" + mSelectedList.size() + "本)");
                    mTvDelete.setEnabled(true);
                    mTvMove.setEnabled(true);
                    mTvMoveOut.setEnabled(true);
                } else {
                    mTvDelete.setTextColor(getResources().getColor(R.color.md_grey_400));
                    mTvMove.setTextColor(getResources().getColor(R.color.md_grey_400));
                    mTvMoveOut.setTextColor(getResources().getColor(R.color.md_grey_400));
                    mTvDelete.setText("删除");
                    mTvDelete.setEnabled(false);
                    mTvMove.setText("移至分组");
                    mTvMoveOut.setText("移出分组");
                    mTvMove.setEnabled(false);
                    mTvMoveOut.setEnabled(false);
                }
                if (dataCanBeRemoved.size() > 0 && mSelectedList.size() == dataCanBeRemoved.size()) {
                    mTvSelectAll.setText("取消全选");
                } else {
                    mTvSelectAll.setText("全选");
                }
            } else {
                mMenuBottom.setVisibility(View.GONE);
                mIvBatch.clearColorFilter();
                mIvBatch.setImageResource(R.mipmap.base_edit_normal);
                mTvDelete.setTextColor(getResources().getColor(R.color.md_grey_400));
                mTvMove.setTextColor(getResources().getColor(R.color.md_grey_400));
                mTvMoveOut.setTextColor(getResources().getColor(R.color.md_grey_400));
                mTvDelete.setEnabled(false);
                mTvDelete.setText("删除");
                mTvSelectAll.setText("全选");
                mTvMove.setText("移至分组");
                mTvMove.setEnabled(false);
                mTvMoveOut.setText("移出分组");
                mTvMoveOut.setEnabled(false);
            }

        }

    }

    private void refreshUI() {
        mRecyclerView.setVisibility(View.VISIBLE);

        refreshMenu();
        if (isSwitchEnable) {
            if (isListMode) {
                mListAdapter.notifyDataSetChanged();
            } else {
                mGridAdapter.notifyDataSetChanged();
            }
        } else {
            mListAdapter.notifyDataSetChanged();
        }
    }

    private void eventRefreshView() {
        mSmartRefreshLayout.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() {
            @Override
            public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
                refreshLayout.finishLoadMore(LOAD_MORE_DELAYED);
                loadMore();
            }

            @Override
            public void onRefresh(@NonNull RefreshLayout refreshLayout) {
                refreshLayout.finishRefresh(REFRESH_DELAYED);
//                refresh();
                refreshDone();
            }
        });

    }

    private void eventRecyclerView() {

        mListAdapter.setOnItemClickListener(((adapter, view, position) -> {
            if (selectStateEnable) {
                T obj = mListAdapter.getItem(position);
                if(obj == null || !obj.canMove()){
                    return;
                }
                if (mSelectedList.contains(obj)) {
                    mSelectedList.remove(obj);
                } else {
                    mSelectedList.add(obj);
                }
                refreshUI();
            } else {
                onItemClickListener(adapter, view, position);
            }
        }));

        mListAdapter.setOnItemChildClickListener((((adapter, view, position) -> {
            if (selectStateEnable) {
                T obj = mListAdapter.getItem(position);
//                if(obj == null || !obj.canMove()){
//                    return;
//                }
                if (mSelectedList.contains(obj)) {
                    mSelectedList.remove(obj);
                } else {
                    mSelectedList.add(obj);
                }
                refreshUI();
            } else {
                onItemChildClickListener(adapter, view, position);
            }
        })));

        mListAdapter.setOnItemLongClickListener(((adapter, view, position) -> {
            if (!selectStateEnable && mListAdapter.getData().get(position).canMove()) {
                mSelectedList.clear();
                selectStateEnable = true;
//                T obj = mListAdapter.getItem(position);
//                if(obj != null && obj.canMove()){
                    mSelectedList.add(mListAdapter.getData().get(position));
//                }
                onSelectStateChanged(true);
                refreshUI();
            }
            return true;


        }));

        if (isSwitchEnable && mGridAdapter != null) {
            mGridAdapter.setOnItemClickListener(mListAdapter.getOnItemClickListener());
            mGridAdapter.setOnItemLongClickListener(mListAdapter.getOnItemLongClickListener());
            mGridAdapter.setOnItemChildClickListener(mListAdapter.getOnItemChildClickListener());
        }
    }

    private void eventSelectAll() {
        mTvSelectAll.setOnClickListener((view -> {

            if (mListAdapter.getData().size() == 0) {
                return;
            }
            if (dataCanBeRemoved.size() > 0 && mSelectedList.size() == dataCanBeRemoved.size()) {
                mSelectedList.clear();
            } else {
                mSelectedList.clear();
                mSelectedList.addAll(dataCanBeRemoved);
                if(dataCanBeRemoved.size() == 0){
                    ToastUtils.show("分组无法被选择哦~");
                }
            }
            refreshUI();
        }));
    }

    private void eventDelete() {
        mTvDelete.setOnClickListener((view -> {

            if (mListAdapter.getData().size() == 0) {
                return;
            }
            //TODO 顺序
            List<T> copyList = new ArrayList<>(mSelectedList);
            deleteItems(copyList);
            mSelectedList.clear();
        }));

    }

    private void eventMove() {
        mTvMove.setOnClickListener((view -> {

            if (mListAdapter.getData().size() == 0) {
                return;
            }
            moveItems(mSelectedList);
        }));
    }

    private void eventMoveOut() {
        mTvMoveOut.setOnClickListener((view ->{
            if(mListAdapter.getData().size() == 0){
                return;
            }
            moveItemsOut(mSelectedList);
        }));
    }

    private void eventListOrGrid() {
        mIvListOrGrid.setOnClickListener((view -> {
            isListMode = !isListMode;
            setupListOrGrid();
            onListOrGridStateChanged(isListMode);
        }));
    }

    private void setupListOrGrid() {

//        if (mListAdapter.getData().size() == 0) {
//            refreshUI();
//            return;
//        }
        if (isListMode) {
            mRecyclerView.setAdapter(mListAdapter);
            mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
            mListAdapter.setEmptyView(R.layout.layout_empty_default);
        } else {
//                if (!mGridHasBindToView) {
//                    mGridHasBindToView = true;
//                    mGridAdapter.bindToRecyclerView(mRecyclerView);
//                }
            mRecyclerView.setAdapter(mGridAdapter);
            mRecyclerView.setLayoutManager(new GridLayoutManager(getContext(), 3));
            mGridAdapter.setEmptyView(R.layout.layout_empty_default);
        }
        refreshUI();
    }

    private void eventBatch() {
        mIvBatch.setOnClickListener((view -> {
            performBatchAction();
        }));
    }

    public void performBatchAction() {

        if (mListAdapter.getData().size() == 0) {
            return;
        }
        mSelectedList.clear();
        selectStateEnable = !selectStateEnable;
        onSelectStateChanged(selectStateEnable);
        refreshUI();
    }

    protected void refresh() {
        dealWithData();
        refreshUI();
    }

    protected void refreshDone() {
        refreshUI();
    }

    protected void loadMore() {

    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    public RVLayoutType getLayoutType() {
        return isListMode ? RVLayoutType.LIST : RVLayoutType.GRID;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && selectStateEnable) {
            mSelectedList.clear();
            selectStateEnable = false;
            onSelectStateChanged(false);
            refreshUI();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    public interface Movable{
        boolean canMove();
    }
}
